package com.lyy.system.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lyy.common.utils.*;
import com.lyy.common.utils.excel.ExcelUtils;
import com.lyy.common.utils.jxls.JxlsExport;
import com.lyy.system.pojo.SysDict;
import com.lyy.system.service.SysDictService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 字典表(SysDict)表控制层
 *
 * @author Yw
 * @since 2021-02-01 17:20:17
 */
@RestController
@RequestMapping("/sysDict")
public class SysDictController {
    /**
     * 服务对象
     */
    @Resource
    private SysDictService sysDictService;

    /**
     * 创建字典表
     * /sysDict/createSysDict
     * { "value":"数据值",  "label":"标签名",  "type":"类型",  "description":"描述",  "sort":"排序",  "delFlag":"是否删除,0否,1是" }
     *
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @PostMapping("/createSysDict")
    public Map<String, Object> createSysDict(SysDict sysDict) {
        AssertUtils.notNull(sysDict.getValue(), "数据值不能为空");
        AssertUtils.notNull(sysDict.getLabel(), "标签名不能为空");
        AssertUtils.notNull(sysDict.getType(), "类型不能为空");
        AssertUtils.notNull(sysDict.getDescription(), "描述不能为空");
        AssertUtils.notNull(sysDict.getSort(), "排序不能为空");
        AssertUtils.notNull(sysDict.getDelFlag(), "是否删除,0否,1是不能为空");
        sysDictService.createSysDict(sysDict);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 根据主键修改字典表
     * /sysDict/updateSysDict
     * { "id":"字典id",  "value":"数据值",  "label":"标签名",  "type":"类型",  "description":"描述",  "sort":"排序",  "delFlag":"是否删除,0否,1是" }
     *
     * @param id          字典id
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @PutMapping("/updateSysDict")
    public Map<String, Object> updateSysDict(SysDict sysDict) {
        AssertUtils.notNull(sysDict.getId(), "字典id不能为空");
        AssertUtils.notNull(sysDict.getValue(), "数据值不能为空");
        AssertUtils.notNull(sysDict.getLabel(), "标签名不能为空");
        AssertUtils.notNull(sysDict.getType(), "类型不能为空");
        AssertUtils.notNull(sysDict.getDescription(), "描述不能为空");
        AssertUtils.notNull(sysDict.getSort(), "排序不能为空");
        AssertUtils.notNull(sysDict.getDelFlag(), "是否删除,0否,1是不能为空");
        sysDictService.updateSysDict(sysDict);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 根据主键获取单个字典表
     * /sysDict/getSysDict
     * { "id":"字典id" }
     *
     * @param id 字典id
     * @return
     */
    @GetMapping("/getSysDict")
    public Map<String, Object> getSysDict(SysDict sysDict) {
        AssertUtils.notNull(sysDict.getId(), "字典id不能为空");
        SysDict entity = sysDictService.getSysDict(sysDict);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("sysDict", entity);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 根据主键删除字典表
     * /sysDict/deleteSysDict
     * { "id":"字典id" }
     *
     * @param id 字典id
     * @return
     */
    @DeleteMapping("/deleteSysDict")
    public Map<String, Object> deleteSysDict(SysDict sysDict) {
        AssertUtils.notNull(sysDict.getId(), "字典id不能为空");
        sysDictService.deleteSysDict(sysDict);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * 查询字典表列表
     * /sysDict/selectSysDictList
     * { "id":"字典id",  "value":"数据值",  "label":"标签名",  "type":"类型",  "description":"描述",  "sort":"排序",  "delFlag":"是否删除,0否,1是" }
     *
     * @param id          字典id
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @GetMapping("/selectSysDictList")
    public Map<String, Object> selectSysDictList(SysDict sysDict) {
        List<SysDict> sysDicts = sysDictService.selectSysDictList(sysDict);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("sysDicts", sysDicts);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }

    /**
     * 查询字典表列表
     * /sysDict/selectSysDictCount
     * { "id":"字典id", "value":"数据值", "label":"标签名", "type":"类型", "description":"描述", "sort":"排序", "delFlag":"是否删除,0否,1是"}
     *
     * @param id          字典id
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @GetMapping("/selectSysDictCount")
    public Map<String, Object> selectSysDictCount(SysDict sysDict) {
        int count = sysDictService.selectSysDictCount(sysDict);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("count", count);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 查询字典表列表分页
     * /sysDict/selectSysDictPage
     * { "id":"字典id",  "value":"数据值",  "label":"标签名",  "type":"类型",  "description":"描述",  "sort":"排序",  "delFlag":"是否删除,0否,1是" ,"pageNum":"页码","pageSize":"条数"}
     *
     * @param pageNum     页码
     * @param pageSize    页数
     * @param id          字典id
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @GetMapping("/selectSysDictPage")
    public Map<String, Object> selectSysDictPage(SysDict sysDict, Integer pageNum, Integer pageSize) {
        AssertUtils.notNull(pageNum, "页码不能为空!");
        AssertUtils.notNull(pageSize, "条数不能为空!");
        PageHelper.startPage(pageNum, pageSize);
        List<SysDict> sysDicts = sysDictService.selectSysDictList(sysDict);
        PageInfo<SysDict> pageInfo = new PageInfo<>(sysDicts);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pageInfo", pageInfo);
        return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
    }


    /**
     * 导出字典表
     * /sysDict/exportSysDictExcel
     * { "id":"字典id",  "value":"数据值",  "label":"标签名",  "type":"类型",  "description":"描述",  "sort":"排序",  "delFlag":"是否删除,0否,1是" }
     *
     * @param id          字典id
     * @param value       数据值
     * @param label       标签名
     * @param type        类型
     * @param description 描述
     * @param sort        排序
     * @param delFlag     是否删除,0否,1是
     * @return
     */
    @GetMapping("/exportSysDictExcel")
    public void exportSysDictExcel(HttpServletRequest request, HttpServletResponse response, SysDict sysDict) {
        List<SysDict> sysDicts = sysDictService.selectSysDictList(sysDict);
        if (CommonUtils.isNotEmpty(sysDicts)) {
            List<String> titles = new ArrayList<>();
            titles.add(" 序号 ");
            titles.add(" 数据值 ");
            titles.add(" 标签名 ");
            titles.add(" 类型 ");
            titles.add(" 描述 ");
            titles.add(" 排序 ");
            titles.add(" 是否删除,0否,1是 ");
            List<List<String>> values = new ArrayList<>();
            int k = 0;
            for (SysDict entity : sysDicts) {
                List<String> value = new ArrayList<>();
                value.add((++k) + "");
                value.add(entity.getValue());
                value.add(entity.getLabel());
                value.add(entity.getType());
                value.add(entity.getDescription());
                value.add(entity.getSort() + "");
                value.add(entity.getDelFlag());
                values.add(value);
            }
            String address = Constants.address + "/wisdom/template/customTemplate.xls";
            String excelName = "字典表.xls";
            Map<String, Object> beans = new HashMap<>();
            beans.put("titles", titles);
            beans.put("values", values);
            beans.put("date", DateUtils.formatDateTime(new Date()));
            JxlsExport.export(request, response, beans, excelName, address);
        }
    }

    /**
     * 根据主键逻辑删除字典表
     * /sysDict/deleteSysDictLogic
     * { "id":"字典id" }
     *
     * @param id 字典id
     * @return
     */
    @PutMapping("/deleteSysDictLogic")
    public Map<String, Object> deleteSysDictLogic(SysDict sysDict) {
        sysDict.setDelFlag("1");
        sysDictService.updateSysDict(sysDict);
        return ResultUtils.getResult(ResultInfo.SUCCESS);
    }

    /**
     * /sysDict/importSysDictExcel  从excel表导入字典表
     * 导入excel文件
     * {"file":"excel文件"}
     *
     * @param file excel文件
     */
    @PostMapping("/importSysDictExcel")
    public Map<String, Object> importSysDictExcel(MultipartFile file) {
        if (file.isEmpty()) {
            return ResultUtils.getResult(ResultInfo.UPLOAD_NOT_EXISTS);
        }
        // 文件名称
        String fileName = file.getOriginalFilename();
        if (StringUtils.isBlank(fileName)) {
            return ResultUtils.getResult(ResultInfo.UPLOAD_NOT_EXISTS);
        }
        try {
            InputStream inputStream = file.getInputStream();
            //创建工作簿
            Workbook wb = null;
            //判断表格格式
            if (fileName.toLowerCase().endsWith("xls")) {
                wb = new HSSFWorkbook(inputStream);
            } else if (fileName.toLowerCase().endsWith("xlsx")) {
                wb = new XSSFWorkbook(inputStream);
            } else {
                return ResultUtils.getResult(ResultInfo.UPLOAD_TYPE_ERROR);
            }
            List<SysDict> sysDicts = new ArrayList<>();
            List<Map<String, String>> resultMap = new ArrayList<>();
            Map<String, String> result = null;
            SysDict sysDict = null;
            // 获取工作表的第一个Sheet
            Sheet hssfSheet = wb.getSheetAt(0);
            if (hssfSheet != null) {
                int index = -1;
                for (int rowNum = 0; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                    Row hssfRow = hssfSheet.getRow(rowNum);
                    if (hssfRow != null) {
                        if (ExcelUtils.getValue(hssfRow.getCell(0)).contains("数据值") &&
                                ExcelUtils.getValue(hssfRow.getCell(1)).contains("标签名") &&
                                ExcelUtils.getValue(hssfRow.getCell(2)).contains("类型") &&
                                ExcelUtils.getValue(hssfRow.getCell(3)).contains("描述") &&
                                ExcelUtils.getValue(hssfRow.getCell(4)).contains("排序") &&
                                ExcelUtils.getValue(hssfRow.getCell(5)).contains("是否删除,0否,1是")) {
                            index = ++rowNum;
                            break;
                        }
                    }
                }

                if (index == -1) {
                    result = new HashMap<>();
                    result.put("reason", "excel模板不正确");
                    result.put("status", "1");
                    resultMap.add(result);
                    Map<String, Object> map = new HashMap<>();
                    map.put("resultMap", resultMap);
                    return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
                }

                // 循环行Row
                for (int rowNum = index; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
                    Row hssfRow = hssfSheet.getRow(rowNum);
                    if (hssfRow != null) {
                        if (StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(0))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(1))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(2))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(3))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(4))) &&
                                StringUtils.isBlank(ExcelUtils.getValue(hssfRow.getCell(5)))) {
                            continue;
                        }
                        sysDict = new SysDict();
                        String value = ExcelUtils.getValue(hssfRow.getCell(0));//数据值
                        if (StringUtils.isBlank(value)) {
                            result = new HashMap<>();
                            result.put("reason", "数据值不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setValue(value);
                        String label = ExcelUtils.getValue(hssfRow.getCell(1));//标签名
                        if (StringUtils.isBlank(label)) {
                            result = new HashMap<>();
                            result.put("reason", "标签名不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setLabel(label);
                        String type = ExcelUtils.getValue(hssfRow.getCell(2));//类型
                        if (StringUtils.isBlank(type)) {
                            result = new HashMap<>();
                            result.put("reason", "类型不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setType(type);
                        String description = ExcelUtils.getValue(hssfRow.getCell(3));//描述
                        if (StringUtils.isBlank(description)) {
                            result = new HashMap<>();
                            result.put("reason", "描述不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setDescription(description);
                        String sort = ExcelUtils.getValue(hssfRow.getCell(4));//排序
                        if (StringUtils.isBlank(sort)) {
                            result = new HashMap<>();
                            result.put("reason", "排序不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setSort(Integer.valueOf(sort));
                        String delFlag = ExcelUtils.getValue(hssfRow.getCell(5));//是否删除,0否,1是
                        if (StringUtils.isBlank(delFlag)) {
                            result = new HashMap<>();
                            result.put("reason", "是否删除,0否,1是不能为空！");
                            result.put("status", "1");
                            resultMap.add(result);
                            continue;
                        }
                        sysDict.setDelFlag(delFlag);
                        sysDicts.add(sysDict);
                    }
                }
                if (CommonUtils.isNotEmpty(sysDicts)) {
                    resultMap.addAll(sysDictService.importSysDictExcel(sysDicts));
                }
            }
            inputStream.close();
            Map<String, Object> map = new HashMap<>();
            map.put("resultMap", resultMap);
            return ResultUtils.getResult(ResultInfo.SUCCESS, "", map);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.getResult(ResultInfo.ERROR);
        }
        return ResultUtils.getResult(ResultInfo.FAILED);
    }
}